package threadjuc;

import java.util.Timer;
import java.util.concurrent.*;

/**
 * @author zxl
 * @version 1.0
 * @date 2021/10/27 19:39
 * 基本工具类
 */
public class Juc10 {
    public static void main(String[] args) {
        test1();
        test2();
        test3();
    }

    /**
     * CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后
     */
    private static void test1() {
        //设置总数为10
        CountDownLatch countDownLatch = new CountDownLatch(10);
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                countDownLatch.countDown();  //数量-1
                System.out.println(Thread.currentThread().getName()+"走了");
            },String.valueOf(i)).start();
        }

        try {
            countDownLatch.await();  //当计数器为0时往下走
            System.out.println("完毕");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * CyclicBarrier一般用于一组线程互相等待至某个状态，然后这一组线程再同时执行
     */
    private static void test2() {
        //当计数到7时 执行第二个参数的线程
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
            System.out.println("结束");
        });

        for (int i = 0; i < 7; i++) {
            final int a = i;
            new Thread(()->{
                System.out.println(a);
                try {
                    //等待
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

    /**
     * samaphore其实和锁有点类似，它一般用于控制对某组资源的访问权限
     */
    private static void test3(){
        //线程数量   限流
        //控制线程进入的数量
        Semaphore semaphore = new Semaphore(3);
        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                try {
                    //得到 ，如果满了，则等待被释放
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"进来了");
                    TimeUnit.SECONDS.sleep(2);
                    System.out.println(Thread.currentThread().getName()+"离开了");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    //释放  当前的线程释放，唤醒等待的线程
                    semaphore.release();
                }
            },String.valueOf(i)).start();
        }
    }
}
